from fastapi import APIRouter, UploadFile, File, Form, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Optional, List
import os
import shutil
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
import requests
import json

router = APIRouter()

class LocationInfo(BaseModel):
    latitude: float
    longitude: float
    address: Optional[str] = None

class BusStationInfo(BaseModel):
    station_name: str
    distance: float  # 距离（米）
    bus_lines: List[str]  # 经过的公交线路
    latitude: float
    longitude: float
    address: str

class BusStationResponse(BaseModel):
    status: str
    message: str
    current_location: LocationInfo
    nearby_stations: List[BusStationInfo]

class RouteRequest(BaseModel):
    destination_station: str  # 目标公交站名称
    destination_lat: float    # 目标公交站纬度
    destination_lng: float    # 目标公交站经度
    origin_lat: float         # 起始位置纬度
    origin_lng: float         # 起始位置经度
    origin_address: Optional[str] = None

class RouteInfo(BaseModel):
    route_description: str    # 路线描述
    total_distance: str       # 总距离
    estimated_time: str       # 预计时间
    transfer_count: int       # 换乘次数
    steps: List[str]          # 详细步骤

class RouteResponse(BaseModel):
    status: str
    message: str
    routes: List[RouteInfo]

def extract_gps_from_image(image_path: str) -> Optional[LocationInfo]:
    """从图片EXIF信息中提取GPS坐标"""
    try:
        image = Image.open(image_path)
        exifdata = image.getexif()
        
        if exifdata is None:
            return None
            
        # 查找GPS信息
        for tag_id in exifdata:
            tag = TAGS.get(tag_id, tag_id)
            if tag == "GPSInfo":
                gps_data = exifdata[tag_id]
                
                # 解析GPS坐标
                lat = gps_data.get(2)  # GPSLatitude
                lat_ref = gps_data.get(1)  # GPSLatitudeRef
                lon = gps_data.get(4)  # GPSLongitude  
                lon_ref = gps_data.get(3)  # GPSLongitudeRef
                
                if lat and lon:
                    # 转换为十进制度数
                    latitude = convert_to_degrees(lat)
                    longitude = convert_to_degrees(lon)
                    
                    # 处理南纬和西经
                    if lat_ref == 'S':
                        latitude = -latitude
                    if lon_ref == 'W':
                        longitude = -longitude
                        
                    return LocationInfo(
                        latitude=latitude,
                        longitude=longitude
                    )
    except Exception as e:
        print(f"提取GPS信息失败: {e}")
        return None
    
    return None

def convert_to_degrees(gps_coord):
    """将GPS坐标从度分秒格式转换为十进制度数"""
    degrees = float(gps_coord[0])
    minutes = float(gps_coord[1])
    seconds = float(gps_coord[2])
    return degrees + (minutes / 60.0) + (seconds / 3600.0)

async def get_nearby_bus_stations(location: LocationInfo) -> List[BusStationInfo]:
    """
    调用AI智能体API获取附近公交站信息
    集成阿里云DashScope AI服务
    """
    try:
        # 导入阿里云AI服务
        from dashscope import Application
        from http import HTTPStatus
        import re
        
        # 构建AI提示词 - 更精确的要求返回结构化数据
        prompt = f"""
        我需要查找GPS坐标({location.latitude}, {location.longitude})附近的公交站信息。

        请严格按照以下JSON格式返回数据，不要包含任何其他文字说明：

        {{
            "stations": [
                {{
                    "station_name": "公交站名称",
                    "distance": 距离数字(米),
                    "bus_lines": ["线路1", "线路2"],
                    "latitude": 纬度数字,
                    "longitude": 经度数字,
                    "address": "详细地址"
                }}
            ]
        }}

        要求：
        1. 返回3-5个最近的公交站
        2. distance必须是数字(米)
        3. 坐标必须是准确的数字
        4. 只返回JSON，不要其他解释文字
        """
        
        # 调用AI服务
        response = Application.call(
            api_key=os.getenv("DASHSCOPE_API_KEY") or "sk-1d28fd9d2a5f4d228f0d15a6f81b81b3",
            app_id='5b7b57229d4c4f68a4189c9c3889f937',
            prompt=prompt
        )
        
        if response.status_code == HTTPStatus.OK:
            ai_result = response.output.text.strip()
            print(f"🤖 AI返回原始结果: {ai_result}")
            
            try:
                # 尝试提取JSON部分
                json_match = re.search(r'\{.*\}', ai_result, re.DOTALL)
                if json_match:
                    json_str = json_match.group()
                    ai_data = json.loads(json_str)
                    
                    stations = []
                    if 'stations' in ai_data:
                        for station_data in ai_data['stations']:
                            try:
                                station = BusStationInfo(
                                    station_name=station_data.get('station_name', '未知站点'),
                                    distance=float(station_data.get('distance', 0)),
                                    bus_lines=station_data.get('bus_lines', []),
                                    latitude=float(station_data.get('latitude', location.latitude)),
                                    longitude=float(station_data.get('longitude', location.longitude)),
                                    address=station_data.get('address', '地址未知')
                                )
                                stations.append(station)
                            except (ValueError, TypeError) as e:
                                print(f"⚠️  解析站点数据失败: {e}")
                                continue
                    
                    if stations:
                        print(f"✅ 成功解析 {len(stations)} 个公交站")
                        return stations
                    else:
                        print("⚠️  AI返回数据为空，使用备用数据")
                        
            except json.JSONDecodeError as e:
                print(f"⚠️  JSON解析失败: {e}")
                print(f"AI返回内容: {ai_result}")
                
        else:
            print(f"❌ AI服务调用失败: {response.status_code}")
            if hasattr(response, 'message'):
                print(f"错误信息: {response.message}")
                
    except Exception as e:
        print(f"❌ AI服务异常: {e}")
        import traceback
        traceback.print_exc()
    
    # 备用数据 - 当AI服务不可用时使用
    print("🔄 使用备用模拟数据")
    mock_stations = [
        BusStationInfo(
            station_name="智能识别站点A",
            distance=120,
            bus_lines=["快速1路", "市区2路", "环线3路"],
            latitude=location.latitude + 0.0008,
            longitude=location.longitude + 0.0012,
            address=f"位置({location.latitude:.4f}, {location.longitude:.4f})附近"
        ),
        BusStationInfo(
            station_name="AI推荐站点B", 
            distance=280,
            bus_lines=["主干线5路", "支线7路", "夜班9路"],
            latitude=location.latitude - 0.0015,
            longitude=location.longitude + 0.0008,
            address=f"距离目标点280米处"
        ),
        BusStationInfo(
            station_name="智能站点C",
            distance=350,
            bus_lines=["地铁接驳线", "旅游专线"],
            latitude=location.latitude + 0.0018,
            longitude=location.longitude - 0.0010,
            address=f"坐标({location.latitude:.4f}, {location.longitude:.4f})周边"
        )
    ]
    
    return mock_stations

async def get_route_plan(request: RouteRequest) -> List[RouteInfo]:
    """
    调用AI智能体获取路线规划信息
    """
    try:
        from dashscope import Application
        from http import HTTPStatus
        import re
        
        # 构建AI提示词
        prompt = f"""
        请为我规划从起始位置到目标公交站的路线：
        
        起始位置：
        - 纬度: {request.origin_lat}
        - 经度: {request.origin_lng}
        - 地址: {request.origin_address or '用户当前位置'}
        
        目标公交站：
        - 站点名称: {request.destination_station}
        - 纬度: {request.destination_lat}
        - 经度: {request.destination_lng}
        
        请严格按照以下JSON格式返回路线规划数据：
        
        {{
            "routes": [
                {{
                    "route_description": "路线描述",
                    "total_distance": "总距离",
                    "estimated_time": "预计时间",
                    "transfer_count": 换乘次数(数字),
                    "steps": ["步骤1", "步骤2", "步骤3"]
                }}
            ]
        }}
        
        要求：
        1. 提供2-3种不同的路线方案
        2. 包含步行+公交的组合方案
        3. transfer_count必须是数字
        4. 只返回JSON，不要其他解释文字
        """
        
        # 调用AI服务
        response = Application.call(
            api_key=os.getenv("DASHSCOPE_API_KEY") or "sk-1d28fd9d2a5f4d228f0d15a6f81b81b3",
            app_id='5b7b57229d4c4f68a4189c9c3889f937',
            prompt=prompt
        )
        
        if response.status_code == HTTPStatus.OK:
            ai_result = response.output.text.strip()
            print(f"🗺️ AI路线规划结果: {ai_result}")
            
            try:
                # 尝试提取JSON部分
                json_match = re.search(r'\{.*\}', ai_result, re.DOTALL)
                if json_match:
                    json_str = json_match.group()
                    ai_data = json.loads(json_str)
                    
                    routes = []
                    if 'routes' in ai_data:
                        for route_data in ai_data['routes']:
                            try:
                                route = RouteInfo(
                                    route_description=route_data.get('route_description', '路线规划'),
                                    total_distance=route_data.get('total_distance', '未知距离'),
                                    estimated_time=route_data.get('estimated_time', '未知时间'),
                                    transfer_count=int(route_data.get('transfer_count', 0)),
                                    steps=route_data.get('steps', [])
                                )
                                routes.append(route)
                            except (ValueError, TypeError) as e:
                                print(f"⚠️  解析路线数据失败: {e}")
                                continue
                    
                    if routes:
                        print(f"✅ 成功解析 {len(routes)} 条路线")
                        return routes
                        
            except json.JSONDecodeError as e:
                print(f"⚠️  JSON解析失败: {e}")
                
    except Exception as e:
        print(f"❌ AI路线规划异常: {e}")
    
    # 备用路线数据
    print("🔄 使用备用路线规划数据")
    mock_routes = [
        RouteInfo(
            route_description=f"推荐路线：步行至{request.destination_station}",
            total_distance="约500米",
            estimated_time="步行6分钟",
            transfer_count=0,
            steps=[
                f"从当前位置({request.origin_address or '起始点'})出发",
                "向东北方向步行200米",
                "右转继续步行300米",
                f"到达目标公交站：{request.destination_station}"
            ]
        ),
        RouteInfo(
            route_description=f"公交路线：搭乘公交到{request.destination_station}",
            total_distance="约1.2公里",
            estimated_time="15分钟",
            transfer_count=1,
            steps=[
                "步行到最近的公交站(约100米)",
                "搭乘快速公交线路",
                "行驶约10分钟",
                f"在{request.destination_station}下车"
            ]
        )
    ]
    
    return mock_routes

@router.post("/api/bus-station/upload-image", response_model=BusStationResponse)
async def upload_image_and_find_stations(
    file: UploadFile = File(..., description="上传的图片文件"),
    fallback_lat: Optional[float] = Form(None, description="备用纬度"),
    fallback_lng: Optional[float] = Form(None, description="备用经度")
):
    """
    上传图片并查找附近公交站
    如果图片没有GPS信息，使用备用坐标
    """
    if not file.content_type.startswith('image/'):
        raise HTTPException(status_code=400, detail="请上传图片文件")
    
    # 保存上传的图片
    upload_dir = "uploaded_images"
    os.makedirs(upload_dir, exist_ok=True)
    
    file_path = os.path.join(upload_dir, file.filename)
    with open(file_path, "wb") as buffer:
        shutil.copyfileobj(file.file, buffer)
    
    try:
        # 尝试从图片提取GPS信息
        location = extract_gps_from_image(file_path)
        
        # 如果图片没有GPS信息，使用备用坐标
        if not location and fallback_lat and fallback_lng:
            location = LocationInfo(
                latitude=fallback_lat,
                longitude=fallback_lng,
                address="用户提供的位置"
            )
        
        if not location:
            return BusStationResponse(
                status="error",
                message="无法获取位置信息，请提供GPS坐标或上传带有位置信息的图片",
                current_location=LocationInfo(latitude=0, longitude=0),
                nearby_stations=[]
            )
        
        # 获取附近公交站信息
        stations = await get_nearby_bus_stations(location)
        
        return BusStationResponse(
            status="success",
            message=f"找到 {len(stations)} 个附近公交站",
            current_location=location,
            nearby_stations=stations
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"处理失败: {str(e)}")
    finally:
        # 清理临时文件
        if os.path.exists(file_path):
            os.remove(file_path)

@router.post("/api/bus-station/by-location", response_model=BusStationResponse)
async def find_stations_by_location(location: LocationInfo):
    """
    根据提供的GPS坐标查找附近公交站
    """
    try:
        stations = await get_nearby_bus_stations(location)
        
        return BusStationResponse(
            status="success",
            message=f"找到 {len(stations)} 个附近公交站",
            current_location=location,
            nearby_stations=stations
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"查询失败: {str(e)}")

@router.post("/api/bus-station/route-plan", response_model=RouteResponse)
async def get_route_to_station(request: RouteRequest):
    """
    获取到指定公交站的路线规划
    """
    try:
        routes = await get_route_plan(request)
        
        return RouteResponse(
            status="success",
            message=f"找到 {len(routes)} 条路线方案",
            routes=routes
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"路线规划失败: {str(e)}")

@router.get("/api/bus-station/test")
async def test_bus_station_api():
    """测试接口"""
    return {
        "message": "公交站查询API正常运行",
        "endpoints": [
            "POST /api/bus-station/upload-image - 上传图片查找公交站",
            "POST /api/bus-station/by-location - 根据坐标查找公交站",
            "POST /api/bus-station/route-plan - 获取公交站路线规划"
        ]
    }
